package com.filldream.fastboot.common.util;

import com.filldream.fastboot.common.entity.ErrContent;
import com.filldream.fastboot.common.exception.GlobalException;
import com.filldream.fastboot.common.entity.B;
import com.filldream.fastboot.common.entity.ErrorCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author RickSun
 * @description 断言工具，用于快速返回
 **/
public class Assert {

    /**
     * 校验数值类型
     * number为null或为0时抛异常
     * @param number   整数数值
     * @param errContent    错误类型
     */
    public static void checkInteger(Integer number, ErrContent errContent){
        if( number == null || number.equals(0) ){
            throw  new GlobalException(errContent);
        }
    }

    /**
     * 校验布尔类型
     * 布尔值为null或false时抛异常
     * @param result    布尔类型值
     * @param errContent    错误类型
     */
    public static void checkBoolean(Boolean result,ErrContent errContent) {
        if (result == null || result.equals(false)) {
            throw new GlobalException(errContent);
        }
    }

    /**
     * 校验布尔类型
     * 布尔值为null或false时抛异常
     * @param result    布尔类型值
     * @param errMsg    自定义错误信息
     */
    public static void checkBoolean(Boolean result,String errMsg) {
        checkBoolean(result,ErrorCode.BASE_ERR.reMsg(errMsg));
    }

    /**
     * 校验布尔类型
     * 布尔类型为true时报错
     * @param result    布尔类型值
     * @param errContent    错误类型
     */
    public static void isBoolean(Boolean result,ErrContent errContent) {
       checkBoolean(!result,errContent);
    }

    /**
     * 校验布尔类型
     * 布尔类型为true时报错
     * @param result    布尔类型值
     * @param errMsg    自定义错误信息
     */
    public static void isBoolean(Boolean result,String errMsg) {
        checkBoolean(!result, ErrorCode.BASE_ERR.reMsg(errMsg));
    }

    /**
     * 检查字符串、数组、集合、Map、是否为null
     * @param object    对象
     * @param errContent 错误类型
     */
    public static void isEmpty(Object object, ErrContent errContent){
        isEmpty(object,errContent,errContent.getContent());
    }

    /**
     * 检查字符串、数组、集合、Map、是否为null
     * @param object    对象
     * @param errContent 错误类型
     * @param errMsg    自定义错误信息
     * @see org.springframework.util.ObjectUtils
     */
    public static void isEmpty(Object object, ErrContent errContent,String errMsg){
        if( ObjectUtils.isEmpty(object) ){
            throw  new GlobalException(errContent,errMsg);
        }
    }

    /**
     * 检查字符串、数组、集合、Map、是否为空或NULL
     * @param object    对象
     * @param errMsg    自定义错误信息
     */
    public static void isEmpty(Object object,String errMsg){
        isEmpty(object,ErrorCode.BASE_ERR.reMsg(errMsg));
    }

    /**
     * 校验字符串是否为空
     * 以下情况会抛异常：
     * 1、""
     * 2、" "
     * 3、NULL
     * 注意与isEmpty方法的区别
     *
     * @param str   字符串
     * @param errMsg   自定义错误类型
     * @see org.apache.commons.lang3.StringUtils
     */
    public static void isBank(String str,String errMsg){
        checkBoolean( !StringUtils.isBlank(str),ErrorCode.BASE_ERR.reMsg(errMsg) );
    }

    /**
     * 校验字符串是否为空
     * 以下情况会抛异常：
     * 1、""
     * 2、" "
     * 3、NULL
     * 注意与isEmpty方法的区别
     *
     * @param str   字符串
     * @param errContent   错误类型
     * @see org.apache.commons.lang3.StringUtils
     */
    public static void isBank(String str,ErrContent errContent){
        isBank(str,errContent.getContent());
    }

    /**
     * 判断对象是否为null
     * @param object    对象
     * @param errContent    错误类型
     */
    public static void isNull( Object object,ErrContent errContent ){
        isEmpty( object,errContent );
    }

    /**
     * 判断多个可变字符串、数组、集合、Map是否为空或空串
     * @param errContent 错误类型
     * @param contents  多个对象
     */
    public static void isEmpty(ErrContent errContent,Object ... contents){
        for (Object content : contents) {
            isEmpty(content,errContent);
        }
    }

    /**
     * 判断多个可变文本是否为空或空串
     * @param contents  多个字符串
     * @param errContent    错误类型
     */
    public static void isEmpty(ErrContent errContent,String ... contents){
        for (String content : contents) {
            if(StringUtils.isBlank(content)){
                throw  new GlobalException(errContent);
            }
        }
    }

    /**
     * 判断返回类是否成功
     * @param resultEntity  基础返回类
     * @param errContent    错误类型
     */
    public static void isOk(B resultEntity, ErrContent errContent) {
        if ( resultEntity == null || !resultEntity.isOk() ) {
            throw new GlobalException(errContent);
        }
    }

    /**
     * 校验密码是否为明码
     * @param password  一次无盐的MD加密后的密码，长度为32位
     */
    public static void checkPwd(String password) {
        isEmpty(password,ErrorCode.BASE_ERR.reMsg("密码不得为空"));
        if( password.length() != 32 ){
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg("密码未经加密，禁止明码传输"));
        }
    }

    /**
     * @author RickSun
     * @Description 正则表达式校验:不满足正则时抛异常
     * @param regex 正则表达式
     * @param text  待验证字符串
     * @param msg  自定义错误信息
     **/
    public static void checkEx(String regex,String text,String msg){
        boolean matches = Pattern.matches(regex, text);
        checkBoolean(matches,ErrorCode.BASE_ERR.reMsg(msg));
    }

    /**
     * @author RickSun
     * @Description 正则表达式校验:满足正则时抛异常
     * @param regex 正则表达式
     * @param text  待验证字符串
     * @param msg  自定义报错信息
     **/
    public static void checkNotEx(String regex,String text,String msg){
        boolean matches = Pattern.matches(regex, text);
        if( matches  ){
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg(msg));
        }
    }

    /**
     * @author RickSun
     * @description 判断List中是否包含指定对象
     * @param obj   对象
     * @param expectList    List集合
     * @param msg   自定义报错信息
     * @return void
     **/
    public static <T> void contain(T obj, List<T> expectList, String msg) {
        if (obj == null || expectList == null) {
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg(msg));
        }
        if (!expectList.contains(obj)) {
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg(msg));
        }
    }

    /**
     * @author RickSun
     * @description 判断数组中是否包含指定对象
     * @param obj   对象
     * @param arr   数组
     * @param msg   自定义报错信息
     * @return void
     **/
    public static <T> void contain(T obj, T[] arr, String msg) {
        if (obj == null || arr == null) {
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg(msg));
        }
        List<Object> list = Arrays.asList(arr);
        contain(obj,list,msg);
    }


    /**
     * @author RickSun
     * @Description 范围校验
     * @param object    需要判断的对象(仅支持字符穿和整型)
     * @param min   最小值
     * @param max   最大值
     * @param errMsg    异常信息
     **/
    public static void range(Object object, Long min, Long max, String errMsg) {
        if (object == null || min == null || max == null) {
            throw new GlobalException(errMsg);
        }
        if (object instanceof Number) {
            checkBoolean(((Number)object).longValue() >= min && ((Number)object).longValue() <= max, ErrorCode.BASE_ERR.reMsg(errMsg));
        } else if (object instanceof CharSequence) {
            checkBoolean(((CharSequence)object).length() >= min && ((CharSequence)object).length() <= max, ErrorCode.BASE_ERR.reMsg(errMsg));
        } else {
            throw new GlobalException(ErrorCode.BASE_ERR.reMsg(errMsg));
        }
    }

    /**
     * 快速报错
     * @param errContent    错误类型及提示
     */
    public static void err(ErrContent errContent){
        throw  new GlobalException(errContent);
    }

    /**
     * 快速报错
     * @param msg   固定错误类型及自定义提示
     */
    public static void err(String msg){
        err(ErrorCode.BASE_ERR.reMsg(msg));
    }

}
